/**
 * ol地图工具
 */
import Polygon from 'ol/geom/Polygon'
import { transform } from "ol/proj";
import coordinateTranslate from "./coordinateTranslate"

const coordinateList = ['EPSG:3857','gcj02','wgs84']

// 计算多点范围
const calcExtent = (points) => {
  let minLng = 0
  let maxLng = 0
  let minLat = 0
  let maxLat = 0
  points.forEach(item => {
    let point = item.get('data')
    // console.log(point)
    point.coordinate[0]
    point.coordinate[1]
    if (minLng === 0) {
      maxLng = point.coordinate[0]
      minLng = point.coordinate[0]
    } else if (point.coordinate[0] > maxLng) {
      maxLng = point.coordinate[0]
    } else if (point.coordinate[0] < minLng) {
      minLng = point.coordinate[0]
    }
    if (minLat === 0) {
      maxLat = point.coordinate[1]
      minLat = point.coordinate[1]
    } else if (point.coordinate[1] > maxLat) {
      maxLat = point.coordinate[1]
    } else if (point.coordinate[1] < minLat) {
      minLat = point.coordinate[1]
    }
  })
  return {minLng,maxLng,minLat,maxLat}
}

// 调整视口
const fitView = (olMap,feature) => {
  let data = feature.get('features')
  let extent = calcExtent(data)
  let polygonData = [
    [extent.minLng, extent.minLat],
    [extent.minLng, extent.maxLat],
    [extent.maxLng, extent.maxLat],
    [extent.maxLng, extent.minLat],
    [extent.minLng, extent.minLat],
  ]
  let polygon = new Polygon([polygonData])
  // console.log(polygon.getExtent())
  olMap.getView().fit(polygon.getExtent(),{
    size: olMap.getSize(),
    padding: [40,60,20,60],
    duration: 1000,
    maxZoom: 20
  })
}

/**
 * 坐标转换
 * @param {String} enter 输入坐标系类型 EPSG:3857 gcj02 wgs84
 * @param {String} leave 输出坐标系类型 EPSG:3857 gcj02 wgs84
 * @param {Array} lngLat 坐标值
 */
const transferOfAxes = (enter,leave,lngLat) => {
  if(!coordinateList.includes(enter) && !coordinateList.includes(leave)){
    throw new Error("Unsupported coordinate system.")
  } 
  let enterIndex = -1
  let leaveIndex = -1
  coordinateList.forEach((item,index) => {
    if(enter === item) enterIndex = index
    if(leave === item) leaveIndex = index
  })
  if(enterIndex === -1 || leaveIndex === -1 || enterIndex === leaveIndex){
    throw new Error("The coordinate type resolves the exception.")
  }
  let lngLatRes = [Number(lngLat[0]),Number(lngLat[1])]
  if(enterIndex < leaveIndex) {
    if(enterIndex < 1) {
      lngLatRes = transform(
        [Number(lngLatRes[0]), Number(lngLatRes[1])],
        "EPSG:3857",
        "EPSG:4326"
      )
      if(leave === 'gcj02') return lngLatRes
    }
    if(enterIndex < 2) {
      lngLatRes = coordinateTranslate.gcj02towgs84(Number(lngLatRes[0]), Number(lngLatRes[1]))
      if(leave === 'wgs84') return lngLatRes
    }
  } else {
    if(enterIndex > 1) {
      lngLatRes = coordinateTranslate.wgs84togcj02(Number(lngLatRes[0]), Number(lngLatRes[1]))
      if(leave === 'gcj02') return lngLatRes
    }
    if(enterIndex > 0) {
      lngLatRes = transform(
        [Number(lngLatRes[0]), Number(lngLatRes[1])],
        "EPSG:4326",
        "EPSG:3857"
      )
      if(leave === 'EPSG:3857') return lngLatRes
    }
  }
}
/**
 * 计算区域
 * @param {Array} points 坐标集合
 */
const calcArea = (points) => {
  if (!(points instanceof Array) || points.length < 1){
    throw new Error ('"Points" is expected to be an array but it\'s not')
  }
  let minLng = 0
  let maxLng = 0
  let minLat = 0
  let maxLat = 0
  points.forEach(item => {
    let point = item
    if (minLng === 0) {
      maxLng = point[0]
      minLng = point[0]
    } else if (point[0] > maxLng) {
      maxLng = point[0]
    } else if (point[0] < minLng) {
      minLng = point[0]
    }
    if (minLat === 0) {
      maxLat = point[1]
      minLat = point[1]
    } else if (point[1] > maxLat) {
      maxLat = point[1]
    } else if (point[1] < minLat) {
      minLat = point[1]
    }
  })
  return {minLng,maxLng,minLat,maxLat}
}

/**
 * 根据传入点支配合适窗口
 * @param {Object} olMap ol地图实例
 * @param {Object} options 配置对象
 * @param {Array} options.points 坐标点集合
 * @param {String} options.CoordinatesType 坐标类型 EPSG:3857 gcj02 wgs84
 * @param {Array} options.padding 适配内边距
 */
const suitWin = (olMap,options) => {
  let {points,CoordinatesType,padding} = options
  if(CoordinatesType && !coordinateList.includes(enter) && !coordinateList.includes(leave)){
    throw new Error("Unsupported coordinate system.")
  } 
  let extent = calcArea(points)
  let polygonData = [
    [extent.minLng, extent.minLat],
    [extent.minLng, extent.maxLat],
    [extent.maxLng, extent.maxLat],
    [extent.maxLng, extent.minLat],
    [extent.minLng, extent.minLat],
  ]
  if(CoordinatesType && CoordinatesType !== 'EPSG:3857') {
    transferOfAxes
    polygonData = polygonData.map(item => {
      return transferOfAxes(CoordinatesType,'EPSG:3857',item)
    })
  }
  let polygon = new Polygon([polygonData])
  olMap.getView().fit(polygon.getExtent(),{
    size: olMap.getSize(),
    padding: padding || [40,60,20,60],
    duration: 1000,
    maxZoom: 20
  })
}

export default { calcExtent, fitView, transferOfAxes, suitWin, calcArea }